package com.geline.sqlbackup.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.dialect.DialectName;
import cn.hutool.db.sql.Condition;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.Wrapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 封装Hutool-SqlBuilder
 * @author: mengxin
 * @date: 2022/7/11 11:46
 */
public class SqlBuilderUtil {


    /**
     * 获取 selectById-sql
     * @param table
     * @param id
     * @return SELECT * FROM t_user WHERE id = ?
     */
    public static String getSelectByIdSql(String table, Object id){
        return getSelectByIdSql(null, table, id);
    }

    public static String getSelectByIdSql(Entity entity, String table, Object id){
        if(StrUtil.isBlankIfStr(id)){
            throw new RuntimeException("id can not be blank !");
        }
        SqlBuilder sqlBuilder = SqlBuilder.create(new Wrapper());
        if(entity != null){
            Set<String> fieldNames = entity.getFieldNames();
            if(fieldNames != null && fieldNames.size()>0){
                sqlBuilder.select(fieldNames);
            }else {
                sqlBuilder.select("*");
            }
        }else {
            sqlBuilder.select("*");
        }
        Condition condition = Condition.parse("id", DynamicSqlUtil.quotaMark(id));
        condition.setPlaceHolder(false);
        sqlBuilder.from(table).where(condition);
        return sqlBuilder.build();
    }

    public static String getSelectByIdsSql(String table, Object... ids){
        return getSelectByIdsSql(null, table, ids);
    }

    public static String getSelectByIdsSql(Entity entity, String table, Object... ids){
        if(StrUtil.isBlankIfStr(ids)){
            throw new RuntimeException("ids can not be blank !");
        }
        SqlBuilder sqlBuilder = SqlBuilder.create(new Wrapper());
        if(entity != null){
            Set<String> fieldNames = entity.getFieldNames();
            if(fieldNames != null && fieldNames.size()>0){
                sqlBuilder.select(fieldNames);
            }else {
                sqlBuilder.select("*");
            }
        }else {
            sqlBuilder.select("*");
        }
        List<String> idList = Stream.of(ids).map(id -> DynamicSqlUtil.quotaMark(id)).collect(Collectors.toList());
        Condition condition = Condition.parse("id", idList);
        condition.setPlaceHolder(false);
        sqlBuilder.from(table).where(condition);
        return sqlBuilder.build();
    }

    /**
     * 获取 select-sql
     * @param table
     * @param bean
     * @return
     */
    public static String getSelectSql(String table, Entity bean){
        Entity entity = Entity.parse(bean).setTableName(table);
        SqlBuilder sqlBuilder = SqlBuilder.create(new Wrapper());
        Set<String> fieldNames = entity.getFieldNames();
        if(fieldNames != null && fieldNames.size()>0){
            sqlBuilder.select(fieldNames);
        }else {
            sqlBuilder.select("*");
        }
        sqlBuilder.from(entity.getTableName());
        List<Condition> conditionList = new ArrayList<>();
        Set<String> keySet = entity.keySet();
        if(keySet != null){
            for(String key : keySet){
                Object value = entity.get(key);
                if(value != null){
                    Condition condition = Condition.parse(key, DynamicSqlUtil.quotaMark(value));
                    condition.setPlaceHolder(false);
                    conditionList.add(condition);
                }
            }
        }
        sqlBuilder.where(conditionList.toArray(new Condition[]{}));
        return sqlBuilder.build();
    }

    /**
     * 获取 insert-sql
     * @param table
     * @param bean
     * @return INSERT INTO t_user (birthDay, createTime, id, userName) VALUES (?, ?, ?, ?)
     */
    public static String getInsertSql(String table, Map<String, Object> bean){
        Entity entity = Entity.parse(bean).setTableName(table);
        SqlBuilder sqlBuilder = SqlBuilder.create(new Wrapper()).insert(entity, DialectName.MYSQL);
        return sqlBuilder.build();
    }

    /**
     * 获取 updateById-sql
     * @param table
     * @param bean
     * @return  UPDATE t_user SET birthDay = ? , createTime = ? , userName = ?  WHERE id = ?
     */
    public static String getUpdateByIdSql(String table, Map<String, Object> bean){
        Object id = bean.get("id");
        if(StrUtil.isBlankIfStr(id)){
            throw new RuntimeException("id can not be blank !");
        }
        Entity entity = Entity.parse(bean).setTableName(table);
        entity.remove("id");
        SqlBuilder sqlBuilder = SqlBuilder.create(new Wrapper());
        Condition condition = Condition.parse("id", DynamicSqlUtil.quotaMark(id));
        condition.setPlaceHolder(false);
        sqlBuilder.update(entity).where(condition);
        return sqlBuilder.build();
    }

    /**
     * 获取 deleteById-sql
     * @param table
     * @param id
     * @return DELETE FROM t_user WHERE id = ?
     */
    public static String getDeleteByIdSql(String table, Object id){
        if(StrUtil.isBlankIfStr(id)){
            throw new RuntimeException("id can not be blank !");
        }
        Condition condition = Condition.parse("id", DynamicSqlUtil.quotaMark(id));
        condition.setPlaceHolder(false);
        SqlBuilder sqlBuilder = SqlBuilder.create(new Wrapper());
        sqlBuilder.delete(table).where(condition);
        return sqlBuilder.build();
    }

    /**
     * 获取 deleteByIds-sql
     * @param table
     * @param ids
     * @return  DELETE FROM t_user WHERE id IN (?,?)
     */
    public static String getDeleteByIdsSql(String table, Object... ids){
        if(StrUtil.isBlankIfStr(ids)){
            throw new RuntimeException("ids can not be blank !");
        }
        List<String> idList = Stream.of(ids).map(id -> DynamicSqlUtil.quotaMark(id)).collect(Collectors.toList());
        Condition condition = Condition.parse("id", idList);
        condition.setPlaceHolder(false);
        SqlBuilder sqlBuilder = SqlBuilder.create(new Wrapper());
        sqlBuilder.delete(table).where(condition);
        return sqlBuilder.build();
    }
}
